#!/bin/bash

# This script is the firewall core, and is able to create all the rules in iptables
# taking this directory listing as database. 
#
# THIS SOFTWARE IS DISTRIBUTED WITH ABSOLUTE NO WARRANRY UNDER TERMS OF GPLv3 LICENSE.
# YOU CAN MODIFY AND REDISTRIBUTE THIS PROGRAM WHITH THE SAME TERMS OF THIS LICENCE.
# The GNU General Public License does not permit incorporating your program into proprietary programs
#
# PLEASE READ COPYING FILE FOR LICENSE DETAIL
#
# This script is useful where a sysadmin want to create rules and chains in a scalable manner,
# quickly and easily, thinking in a "tree mode" and not in a "chain mode". It's also useful
# to make a set of rule and chains created by a client program up and running in a while
# whitout rebooting the system: all that the client program have to do is writing files and
# directory, 'cause all the chains and rules are manteined automagically!!
#
# A '-' sign is appended to the parent directory and the child directory in the structure
# is then added. EX: the FORWARD directory stands for the FORWARD chain.
# If the FORWARD directory contains a subdirectory called 'in' but it doesn't contains a file
# called .default, then a chain called 'FORWARD-in' is created, pointed by the FORWARD chain
# as a target with the matching rule and the link order picked by the .rules file in that
# directory.
#
# If the child directory contains a .rules file it is read to get the number
# of the priority so that the -A command of iptables that links the parent chain to its child
# knows the order to link. It is also used to get the matching rule for that chain.
# To create one or more rules appended to a user defined chain you must create a file for
# each rule you want to add with the name F30rule, where 30 is the priority of the rule for
# the chain. This script will create the rules in that chain according to this number and the
# content of these files that must contain a rule base, ex: -s 192.168.10.0/24 -d 0.0.0.0/0 -j LOG.
#
# It also support iptables-save format in reading and writing mode.
#
# Please try --help for help
#
#
# Requisite: gawk, bash, iptables, grep, basename 
#

# DEFAULTS, overridden by configuration file firerules.conf!!
DEBUG="NO"		# Print out all debug operation
VERBOSE="YES"		# Print out all iptable operations 
SIMULATE="NO"		# Only simulate things. Does not execute
SAVE="NO"		# Produce output in iptables-save format
LOAD="NO"		# Load data from stdin in iptables-save format
INPUT_POLICY="DROP"	# Default INPUT policy
FORWARD_POLICY="DROP"	# Default FORWARD policy
OUTPUT_POLICY="DROP"	# Default OUTPUT policy

# Import configuration variables
base=`dirname $0`
. $base/firerules.conf

# This is to be sure we are in the right directory
DIRPATH="`dirname $0`"
cd $DIRPATH

# Must be 0 here!
errors=0


# Creating the lock file
lock_file="/tmp/firerules.lock"


function Delete_tmp()
{
   # Delete temporary files
   rm -fr tmp/firerules
   mkdir tmp/firerules
   mkdir tmp/firerules/chains
   mkdir tmp/firerules/rules
   mkdir tmp/firerules/ruleset
}

function Default_template()
{
   # Bring up the default template
   for i in `find ./ -type d -maxdepth 1`
   do
      if [ "$i" != "./" ]
      then
         echo "Deleting dir:  $i"
         rm -fr $i
      fi
   done
   touch .default
   echo "Creating filter dir structure"
   mkdir filter
    touch filter/.default
    mkdir filter/FORWARD
    mkdir filter/INPUT
    mkdir filter/OUTPUT
   echo "Creating mangle dir structure"
   mkdir mangle
    touch mangle/.default
    mkdir mangle/FORWARD
    mkdir mangle/INPUT
    mkdir mangle/OUTPUT
    mkdir mangle/POSTROUTING
    mkdir mangle/PREROUTING
   echo "Creating nat dir structure"
   mkdir nat
    touch nat/.default
    mkdir nat/OUTPUT
    mkdir nat/POSTROUTING
    mkdir nat/PREROUTING
   echo "Creating tmp dir structure"
   mkdir tmp
   Delete_tmp
}


function Reset_iptables()
{
   #
   # reset the default policies in the filter table.
   #
   echo "iptables -P INPUT ACCEPT" >> tmp/firerules/ruleset/rules
   echo "iptables -P FORWARD ACCEPT" >> tmp/firerules/ruleset/rules
   echo "iptables -P OUTPUT ACCEPT" >> tmp/firerules/ruleset/rules
   
   #
   # reset the default policies in the nat table.
   #
   echo "iptables -t nat -P PREROUTING ACCEPT" >> tmp/firerules/ruleset/rules
   echo "iptables -t nat -P POSTROUTING ACCEPT" >> tmp/firerules/ruleset/rules
   echo "iptables -t nat -P OUTPUT ACCEPT" >> tmp/firerules/ruleset/rules
   
   #
   # reset the default policies in the mangle table.
   #
   echo "iptables -t mangle -P PREROUTING ACCEPT" >> tmp/firerules/ruleset/rules
   echo "iptables -t mangle -P OUTPUT ACCEPT" >> tmp/firerules/ruleset/rules
   
   #
   # flush all the rules in the filter, mangle and nat tables.
   #
   echo "iptables -F" >> tmp/firerules/ruleset/rules
   echo "iptables -t nat -F" >> tmp/firerules/ruleset/rules
   echo "iptables -t mangle -F" >> tmp/firerules/ruleset/rules
   #
   # erase all chains that's not default in filter, mangle and nat table.
   #
   echo "iptables -X" >> tmp/firerules/ruleset/rules
   echo "iptables -t nat -X" >> tmp/firerules/ruleset/rules
   echo "iptables -t mangle -X" >> tmp/firerules/ruleset/rules
   
}

function Reset_iptables_Save()
{
   if [ "$SAVE" == "YES" ]
   then
      # Save in serialized iptable-save format
      echo "*filter" >> tmp/firerules/ruleset/rules_save
      echo ":INPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":FORWARD ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*nat" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":POSTROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*mangle" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
   fi
}

function Block()
{
   echo "iptables -P INPUT DROP" >> tmp/firerules/ruleset/rules
   echo "iptables -P FORWARD DROP" >> tmp/firerules/ruleset/rules
   echo "iptables -P OUTPUT DROP" >> tmp/firerules/ruleset/rules
   if [ "$SAVE" == "YES" ]
   then
      # Save in serialized iptable-save format
      echo "*filter" >> tmp/firerules/ruleset/rules_save
      echo ":INPUT DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":FORWARD DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*nat" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":POSTROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*mangle" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
   fi
}

function Clean_ALL()
{
   Delete_tmp
   # This function clear all rules, chains and temporary files
   echo "iptables -P INPUT $INPUT_POLICY # Set the default policy for the chain" >> tmp/firerules/ruleset/rules
   echo "iptables -P FORWARD $FORWARD_POLICY # Set the default policy for the chain" >> tmp/firerules/ruleset/rules
   echo "iptables -P OUTPUT $OUTPUT_POLICY # Set the default policy for the chain" >> tmp/firerules/ruleset/rules
   echo "iptables -F # Flush each rule for each chain" >> tmp/firerules/ruleset/rules
   echo "iptables -t nat -F # Flush each rule for each chain" >> tmp/firerules/ruleset/rules
   echo "iptables -t mangle -F # Flush each rule for each chain" >> tmp/firerules/ruleset/rules
   echo "iptables -X # Delete all user chain" >> tmp/firerules/ruleset/rules
   echo "iptables -t nat -X # Delete all user chain" >> tmp/firerules/ruleset/rules
   echo "iptables -t mangle -X # Delete all user chain" >> tmp/firerules/ruleset/rules
   
   if [ "$SAVE" == "YES" ]
   then
      # Save in serialized iptable-save format
      echo "*filter" >> tmp/firerules/ruleset/rules_save
      echo ":INPUT DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":FORWARD DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*nat" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":POSTROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*mangle" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
   fi 
}

function Clean_ALL_Save()
{
   Delete_tmp
   if [ "$SAVE" == "YES" ]
   then
      # Save in serialized iptable-save format
      echo "*filter" >> tmp/firerules/ruleset/rules_save
      echo ":INPUT DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":FORWARD DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT DROP [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*nat" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":POSTROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      echo "*mangle" >> tmp/firerules/ruleset/rules_save
      echo ":PREROUTING ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo ":OUTPUT ACCEPT [0:0]" >> tmp/firerules/ruleset/rules_save
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
   fi
}

function Add_Chain()
{
   if [ "$DEBUG" == "YES" ]
   then
      echo "Debug5: Add_Chain: $1"
   fi
   echo $1 >> tmp/firerules/chains/chains.tmp
   #error=`iptables -A $parent $chainrule -j $chain_to_create`
   #error=`$1`
}

function Add_Chain_Save()
{
   if [ "$DEBUG" == "YES" ]
   then
      echo "Debug5: Add_Chain_Save: $1"
   fi
   echo $1 >> tmp/firerules/chains/chains_save.tmp
}

function Add_chains()
{
   # Order the stack of the matching rules
   cat tmp/firerules/chains/chains.tmp 2>/dev/null| sort -n -f -b > tmp/firerules/chains/chains_ordered.tmp

   z=1
   while [ $z -le `cat tmp/firerules/chains/chains_ordered.tmp | wc -l | awk '{ print $1 }'` ]
   do
      # echo $z
      chainRule=`cat tmp/firerules/chains/chains_ordered.tmp | awk -F '# ' FNR==$z'{ print $2 }'`
      if [ "$DEBUG" == "YES" ]
      then
         echo "Debug6: Add_chains: $chainRule"
      fi
      
      # Creating the rule with iptables in priority order! ;-)
      ##error=`echo $chainRule | bash`
      echo "$chainRule" >> tmp/firerules/ruleset/rules
      let z=z+1
   done
}

function Add_chains_save()
{
   # Order the stack of the matching rules
   cat tmp/firerules/chains/chains_save.tmp 2>/dev/null | sort -n -f -b > tmp/firerules/chains/chains_save_ordered.tmp

   z=1
   while [ $z -le `cat tmp/firerules/chains/chains_save_ordered.tmp | wc -l | awk '{ print $1 }'` ]
   do
      # echo $z
      chainRule=`cat tmp/firerules/chains/chains_save_ordered.tmp | awk -F '# ' FNR==$z'{ print $2 }'`
      if [ "$DEBUG" == "YES" ]
      then
         echo "Debug6: Add_chains: $chainRule"
      fi
      
      # Creating the rule with iptables in priority order! ;-)
      ##error=`echo $chainRule | bash`
      echo "$chainRule" >> tmp/firerules/ruleset/rules-user__save
      let z=z+1
   done
}

function Add_Rule()
{
   # Writing a new temp file with all the rule files to analyze for this chain, order and then execute
   echo "tmp/firerules/rules/rules-$2.tmp" >> tmp/firerules/rules/rules.tmp
   # Adding the rule in the stack
   echo $1 >> tmp/firerules/rules/rules-$2.tmp
   #error=`iptables -A $parent $chainrule -j $chain_to_create`
   #error=`$1`
}

function Add_Rule_Save()
{
   # Writing a new temp file with all the rule files to analyze for this chain, order and then execute
   echo "tmp/firerules/rules/rules-save-$2.tmp" >> tmp/firerules/rules/rules-save.tmp
   # Adding the rule in the stack
   echo $1 >> tmp/firerules/rules/rules-save-$2.tmp
}

function Add_rules()
{
   unset flag
   for filerules in `cat tmp/firerules/rules/rules.tmp 2>/dev/null`
   do
      if [ "$flag" == "$filerules" ]
      then
         # This set of rules is alrady parsed, givin'up
         if [ "$DEBUG" == "YES" ]
         then
	    echo "Debug7: Add_rules: This set of rules is alrady parsed, givin'up..."
	 fi
         continue
      fi
      flag=$filerules
      
      # Sort and get all the files with the rules
      # Order the stack of the rules
      cat $filerules | sort -n -f -b > tmp/firerules/rules/rules_ordered.tmp
   
      z=1
      while [ $z -le `cat tmp/firerules/rules/rules_ordered.tmp | wc -l | awk '{ print $1 }'` ]
      do
         # echo $z
         Rule=`cat tmp/firerules/rules/rules_ordered.tmp | awk -F '# ' FNR==$z'{ print $2 }'`
         if [ "$DEBUG" == "YES" ]
         then
            echo "Debug6: Add_rules: $Rule"
	 fi
         
         # Creating the rule with iptables in priority order! ;-)
         echo "$Rule" >> tmp/firerules/ruleset/rules
         let z=z+1
      done
   done
}

function Add_rules_save()
{
   unset flag
   for filerules in `cat tmp/firerules/rules/rules-save.tmp 2>/dev/null`
   do
      if [ "$flag" == "$filerules" ]
      then
         # This set of rules is alrady parsed, givin'up
         if [ "$DEBUG" == "YES" ]
         then
	    echo "Debug7: Add_rules: This set of rules is alrady parsed, givin'up..."
	 fi
         continue
      fi
      flag=$filerules
      
      # Sort and get all the files with the rules
      # Order the stack of the rules
      cat $filerules | sort -n -f -b > tmp/firerules/rules/rules-save_ordered.tmp
   
      z=1
      while [ $z -le `cat tmp/firerules/rules/rules-save_ordered.tmp | wc -l | awk '{ print $1 }'` ]
      do
         # echo $z
         Rule=`cat tmp/firerules/rules/rules-save_ordered.tmp | awk -F '# ' FNR==$z'{ print $2 }'`
         if [ "$DEBUG" == "YES" ]
         then
            echo "Debug6: Add_rules: $Rule"
	 fi
         
         # Creating the rule with iptables in priority order! ;-)
         echo "$Rule" >> tmp/firerules/ruleset/rules-save
         let z=z+1
      done
   done
}

function Write_ruleset()
{
   z=1
   while [ $z -le `cat tmp/firerules/ruleset/rules | wc -l | awk '{ print $1 }'` ]
   do
      # echo $z
      chainRule=`cat tmp/firerules/ruleset/rules | awk FNR==$z'{ print $0 }'`
      if [ "$DEBUG" == "YES" ]
      then
         echo "Debug8: Add_chains: $chainRule"
      fi
      if [ "$VERBOSE" == "YES" ]
      then
         echo "$chainRule"
      fi
      if [ "$SIMULATE" == "NO" ]
      then
         error=`echo "$chainRule" | bash 2>&1`
      else
         error=
      fi
      if [ "$error" != "" ]
      then
         # Error writing rule to iptables
	 echo "Command: $chainRule"
	 echo "Error: $error"
	 echo "######## COMMAND ########" >> tmp/firerules/ruleset/rules.err
	 echo "$chainRule" >> tmp/firerules/ruleset/rules.err
	 echo "######## ERROR ########" >> tmp/firerules/ruleset/rules.err
	 echo "$error" >> tmp/firerules/ruleset/rules.err
	 echo
	 errors=1
      fi
      let z=z+1
   done
}

function Write_ruleset_save()
{
   z=1
   echo "*filter" >>tmp/firerules/ruleset/rules_save
   cat "tmp/firerules/ruleset/rules-user-save" >>tmp/firerules/ruleset/rules_save 2>/dev/null
   #echo "COMMIT" >>tmp/firerules/ruleset/rules_save
   cat "tmp/firerules/ruleset/rules-user__save" >>tmp/firerules/ruleset/rules_save 2>/dev/null
   while [ $z -le `cat tmp/firerules/ruleset/rules-save 2>/dev/null | wc -l | awk '{ print $1 }'` ]
   do
      # echo $z
      chainRule=`cat tmp/firerules/ruleset/rules-save | awk FNR==$z'{ print $0 }'`
      if [ "$DEBUG" == "YES" ]
      then
         echo "Debug8: Add_chains: $chainRule"
      fi
      #if [ "$VERBOSE" == "YES" ]
      #then
         #echo "$chainRule"
      #fi
         error=
	 echo "$chainRule" >> tmp/firerules/ruleset/rules_save
      if [ "$error" != "" ]
      then
         # Error writing rule to iptables
	 echo "Command: $chainRule"
	 echo "Error: $error"
	 echo "######## COMMAND ########" >> tmp/firerules/ruleset/rules.err
	 echo "$chainRule" >> tmp/firerules/ruleset/rules.err
	 echo "######## ERROR ########" >> tmp/firerules/ruleset/rules.err
	 echo "$error" >> tmp/firerules/ruleset/rules.err
	 echo
	 errors=1
      fi
      let z=z+1
   done
      error=
      echo "COMMIT" >> tmp/firerules/ruleset/rules_save
}


# Options for parameters that set something
for o in $@
do
   if [ "$o" == '--debug' ] || [ "$o" == '-D' ]
   then
      DEBUG="YES"
      continue
   fi
   if [ "$o" == '--save-format' ] || [ "$o" == '-O' ]
   then
      SAVE="YES"
      continue
   fi
   if [ "$o" == '--load-format' ] || [ "$o" == '-R' ]
   then
      LOAD="YES"
      echo "NOT IMPLEMENTED"
      exit 1
      continue
   fi
   if [ "$o" == '--nodebug' ] || [ "$o" == '-d' ]
   then
      DEBUG="NO"
      continue
   fi
   if [ "$o" == '--verbose' ] || [ "$o" == '-V' ]
   then
      VERBOSE="YES"
      continue
   fi
   if [ "$o" == '--noverbose' ] || [ "$o" == '-v' ]
   then
      VERBOSE="NO"
      continue
   fi
   if [ "$o" == '--simulate' ] || [ "$o" == '-S' ]
   then
      SIMULATE="YES"
      continue
   fi
   if [ "$o" == '--nosimulate' ] || [ "$o" == '-s' ]
   then
      SIMULATE="NO"
      continue
   fi
   if [ "$o" == '--cleanup' ] || [ "$o" == '-C' ]
   then
      echo "Cleaning up dirs..."
      Default_template
      exit 0
   fi
   if [ "$o" == '--flush' ] || [ "$o" == '-f' ]
   then
      o2="--flush $o2"
      continue
   fi
   if [ "$o" == '--block' ] || [ "$o" == '-B' ]
   then
      o2="--block $o2"
      continue
   fi

   echo "Usage: `basename $0` [--debug --nodebug --verbose --noverbose --simulate --nosimulate]"
   echo "  --cleanup | -C     - Clean up all rules and chains from disk (delete all!)"
   echo "  --flush | -f       - Reset iptables to default (WARNING: default policies are ACCEPT!)"
   echo "  --block | -B       - Reset iptables and change policies to DROP. Use only locally!"
   echo "  --save-format | -O - Print out as iptables-save format"
   echo "  --load-format | -R - Read in data in iptables-save format"
   echo "  --debug | -D       - Is useful for testing your rule set"
   echo "  --nodebug | -d     - (DEFAULT) Exclude the debug functionality"
   echo "  --verbose | -V     - (DEFAULT) Show what's going on"
   echo "  --noverbose | -v   - Do it silently"
   echo "  --simulate | -S    - Only show what's going on. Dosn't write nothing"
   echo "  --nosimulate | -s  - (DEFAULT) Write out things"
   exit 1
done

# Options for parameters that execute something
for o in $o2
do
   if [ "$o" == '--flush' ] || [ "$o" == '-f' ]
   then
      echo "WARNING! Default policy is ACCEPT!" 1>&2
      echo "Cleaning up tables..." 1>&2
      Delete_tmp

      if [ "$SAVE" == "YES" ]
      then
         Reset_iptables_Save
         #Write_ruleset_Save
	 if [ "$VERBOSE" == "YES" ]
	 then
	    cat tmp/firerules/ruleset/rules_save
	 fi
      else
         Reset_iptables
         Write_ruleset
      fi

      exit 0
   fi
   if [ "$o" == '--block' ] || [ "$o" == '-B' ]
   then
      echo "WARNING! Default policy is DROP!" 1>&2
      echo "Cleaning up tables..." 1>&2
      echo "Changing policies..." 1>&2
      
      if [ "$SAVE" == "YES" ]
      then
         Clean_ALL_Save
         #Write_ruleset_Save
	 if [ "$VERBOSE" == "YES" ]
	 then
	    cat tmp/firerules/ruleset/rules_save
	 fi
      else
         Clean_ALL
         Write_ruleset
      fi
      exit 0
   fi
done


if [ -f $lock_file ]
then
   # The lock_file alrady exist
   echo "CRITICAL: The lock file $lock_file alrady exists."
   echo "Probably a previous instance of `basename $0` failed or was interrupted"
   echo "The lockfile must to be killed by hand. Aborting."
   exit 1
fi

# Create the lockfile
#lockfile -s 2 -r 1 $lock_file
touch $lock_file

# Clear all rules and chains
Clean_ALL

# This is the core of the directory spider that cycles on the structure
for i in `find ./ -type d`
do
   if [ "`echo $i | grep './tmp'`" != "" ]
   then
      # Don't think that temp files are rules or chains to create ;-)
      continue
   fi
   
   if [ "$DEBUG" == "YES" ]
   then
      echo "Debug0: dir: $i"
   fi
   
   # CHAINS SUBSCRIPTION
   if [ "$i" != "./" ] && ! [ -f $i/../.default ]
   then
      # This chain is not created by default. We must create it
      parent=$(basename `(cd $i/.. ; pwd)`)
      table=$(basename `(cd $i/../.. ; pwd)`)
      # echo Parent: $table
      child=`basename $i`
      chain_to_create="$parent-$child"
      # Get the priority of that link to use it in case there are more links
      unset priority
      unset chainrule
      if [ -f $i/.rules ]
      then
         priority=`cat $i/.rules | grep "PRIORITY: " | awk -F 'PRIORITY: ' '{ print $2 }'`
         chainrule=`cat $i/.rules | grep "CHAINRULE: " | awk -F 'CHAINRULE: ' '{ print $2 }'`
         if [ "$DEBUG" == "YES" ]
         then
            echo "Debug3: PRIORITY for PARENT_CHAIN $parent: $priority"
            echo "Debug3: CHAINRULE for PARENT_CHAIN $parent: $chainrule"
	 fi
      fi
      if [ "$DEBUG" == "YES" ]
      then
         echo "Debug1: CHAIN_NAME: $chain_to_create TARGET_OF: $parent"
         echo "Debug2: COMMAND1: iptables -t $table -N $chain_to_create" 
         echo "Debug2: COMMAND2: iptables -t $table -A $parent $chainrule -j $chain_to_create"
      fi
      echo "iptables -t $table -N $chain_to_create" >> tmp/firerules/ruleset/rules
      echo ":$chain_to_create - [0:0]" >> tmp/firerules/ruleset/rules-user-save
      # Push a chain matching rule to the stack
      Add_Chain "$priority# iptables -t $table -A $parent $chainrule -j $chain_to_create"
      Add_Chain_Save "$priority# -A $parent $chainrule -j $chain_to_create"
      #if [ "$SAVE" == "YES" ]
      #then
      #   # Save in serialized iptable-save format
      #   echo "*filter" >> tmp/firerules/ruleset/rules_save
      #   echo "-A $parent $chainrule -j $chain_to_create" >> tmp/firerules/ruleset/rules_save
      #   echo "COMMIT" >> tmp/firerules/ruleset/rules_save
      #fi
      
      # This is the core of the file spider that cycles on the structure
      for j in `find $i/ -name 'F*rule'`
      do
         # This is a rule to add to the chain $chain_to_create
         rule="iptables -t $table -A $chain_to_create `cat $j`"
         rule_save="-A $chain_to_create `cat $j`"
         rulepriority=`basename $j | awk -F 'F' '{ print $2 }'| awk -F 'rule' '{ print $1 }'`

         if [ "$DEBUG" == "YES" ]
         then
            echo Debug4: RULE for $chain_to_create: $rule
	 fi
         #error=`$rule`
         # Push a rule to the stack
         Add_Rule "$rulepriority# $rule" "$chain_to_create"
         Add_Rule_Save "$rulepriority# $rule_save" "$chain_to_create"
         if [ "$DEBUG" == "YES" ]
         then
            echo Debug4: RULE PRIORITY: $rulepriority
	 fi
      done
   fi
done

if [ "$SAVE" != "YES" ]
then
   # Order and then pull all the chain matching rules from the stack: writing to iptables!!
   Add_chains
   # Order and the pull all the rules from the stack: writing to iptables!!
   Add_rules
   # Write these rules in iptables
   Write_ruleset
else
   Add_chains_save
   Add_rules_save
   Write_ruleset_save
   if [ "$VERBOSE" == "YES" ]
   then
      cat tmp/firerules/ruleset/rules_save
   fi
fi

# Deleting the lock file
rm -f $lock_file

if [ $errors -eq 0 ]
then
   # No errors
   exit 0
else
   # Errors
   exit 1
fi
